/*
 *   This File is Part of CuteOgre Game Engine
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *	Copyright 2010 Alexandre Pires ( c.alexandre.pires@gmail.com )
 *  Created on: 2010/08/22
 */

#include "InputManager.h"
#include "ConfigManager.h"
#include "LogManager.h"
#include "RenderManager.h"
#include "StateManager.h"

template<> InputManager* Singleton<InputManager>::ms_Singleton = 0;

void InputManager::init() {

	if (!mShutdown)
		return;

	LogManager::message("InputManager::Starting up");

	LogManager::message("InputManager::Creating Input System");

	int handler;
	QString strHWnd;

	RenderManager::getSingleton().getRenderWindow()->getCustomAttribute("WINDOW", &handler);
	strHWnd.setNum(handler);

	OIS::ParamList paramList;
	paramList.insert(
			OIS::ParamList::value_type("WINDOW", strHWnd.toStdString()));

	mInputManager = OIS::InputManager::createInputSystem(paramList);

	LogManager::message("InputManager::Creating Input Objects");

	mMouse = static_cast<OIS::Mouse*> (mInputManager->createInputObject(
			OIS::OISMouse, true));

	mKeyboard = static_cast<OIS::Keyboard*> (mInputManager->createInputObject(
			OIS::OISKeyboard, true));

	if (!mMouse || !mKeyboard)
		LogManager::exception("InputManager::Error creating Input Objects");

	mMouse->setEventCallback(this);
	mKeyboard->setEventCallback(this);

	int width = ConfigManager::readInt("width", 640);
	int height = ConfigManager::readInt("height", 480);

	const OIS::MouseState &ms = mMouse->getMouseState();
	ms.width = width;
	ms.height = height;

	mShutdown = false;
}

void InputManager::shutdown() {

	if (mShutdown)
		return;

	LogManager::message("InputManager::Shutting down");

	mShutdown = true;

	LogManager::message("InputManager::Destroying Input Objects");

	if (mMouse)
		mInputManager->destroyInputObject(mMouse);

	if (mKeyboard)
		mInputManager->destroyInputObject(mKeyboard);

	LogManager::message("InputManager::Destroying Input Manager");

	OIS::InputManager::destroyInputSystem(mInputManager);
}

void InputManager::updateEvents() {

	if (mShutdown)
		return;

	mMouse->capture();
	mKeyboard->capture();
}

bool InputManager::mouseMoved(const OIS::MouseEvent &rEvt) {
	StateManager::getSingleton().injectMouseMoved(rEvt.state.X.abs,
			rEvt.state.Y.abs, rEvt.state.Z.abs);
	return true;
}

bool InputManager::mousePressed(const OIS::MouseEvent &rEvt,
		OIS::MouseButtonID rButton) {
	StateManager::getSingleton().injectMousePressed(rEvt.state.X.abs,
			rEvt.state.Y.abs, MouseButton(rButton));
	return true;
}

bool InputManager::mouseReleased(const OIS::MouseEvent &rEvt,
		OIS::MouseButtonID rButton) {
	StateManager::getSingleton().injectMouseReleased(rEvt.state.X.abs,
			rEvt.state.Y.abs, MouseButton(rButton));
	return true;
}

bool InputManager::keyPressed(const OIS::KeyEvent &rEvt) {
	StateManager::getSingleton().injectKeyPressed(KeyCode(rEvt.key), rEvt.text);
	return true;
}

bool InputManager::keyReleased(const OIS::KeyEvent &rEvt) {
	StateManager::getSingleton().injectKeyReleased(KeyCode(rEvt.key));
	return true;
}

bool InputManager::buttonPressed(const OIS::JoyStickEvent &rEvt, int rIndex) {
	(void) rEvt;
	(void) rIndex;
	return true;
}

bool InputManager::buttonReleased(const OIS::JoyStickEvent &rEvt, int rIndex) {
	(void) rEvt;
	(void) rIndex;
	return true;
}

bool InputManager::axisMoved(const OIS::JoyStickEvent &rEvt, int rIndex) {
	(void) rEvt;
	(void) rIndex;
	return true;
}

bool InputManager::povMoved(const OIS::JoyStickEvent &rEvt, int rIndex) {
	(void) rEvt;
	(void) rIndex;
	return true;
}
